/*****************************************************************
**                                                              **
**  Copyright (C) 2004 Amlogic,Inc.                             **
**  All rights reserved                                         **
**        Filename : aw_avi_app.c /Project:AVOS                ** 
**        Revision : 1.0                                        **
**                                                              **
*****************************************************************/


#include "includes.h"
#include "AVTimer.h"
#include <app/avi/avi_sub.h>
#include <aw_playlist2.h>
#include "aw_AVI_app.h"
#include "aw_command.h"
#include "../user.h"
#include "menu.h"
#include "aw_gui_app.h"
#include "aw_init_display.h"
#include "aw_sys_app.h"
#include "LogoEvent.h"
#include "filelistevent.h"
#include "aw_init_display.h"
#include "aw_config.h"
#include "aw_msg.h"
#include "MoviePlayBackEvent.h"
#include "chipsupport.h"
#include "ctrlconvert.h"
#include "aw_GPLAYER_app.h"
#include "WinConfirmEvent.h"
#include "DeviceSelectEvent.h"
#include "scrsaver.h"
Playlist_t *avi_playlist;
AVIINFO  info;

#define malloc AVMem_malloc
#define free   AVMem_free

//#define MAX_FF_LEVEL    8   /* 2,4,6,8   4 levels */
//#define MAX_BF_LEVEL    6   /* 2,3,4,5,6 5 levels */
#define MAX_FF_LEVEL    4   /* 2,4,6 3 levels */
#define MAX_BF_LEVEL    4   /* 2,3,4  3 levels */

#define AVI_STATUS_RUNNING    0
#define AVI_STATUS_QUITTING   1
#define AVI_STATUS_SWITCHING  2
#define AVI_STATUS_SKIPPING   3

static char device_removed = 0 ;
#ifdef ZOOM_IN
int reduce_level = 0 ;
#endif
static char avi_processing_status = AVI_STATUS_QUITTING;
static INT32U fffb_level = 0;
static INT32U zoom_level = 0;
static INT32U avi_playing_time = 0xffffffff ;
AVI_SUB_t subpic_status = NO_SUBPIC ;
static PlaylistItem_t *avi_playitem;
extern char gCurOnlyFileName[256] ;
extern int preview_video;
extern INT8U preview_processing;
extern INT32U NODIR_FLAG;
extern INT8U FileListOnShowFlag;
extern INT8U LogoResum;
extern INT8U isMute ;
extern INT8U PlayBackResume ;
extern INT8U PlayBackHome ;
extern INT8U LogoHome ;
extern INT8U GetNextOrPrev ;
#if HOTKEYENABLE
extern char hotkey_flag ;
#endif 
extern INT32U last_hotkey ;
extern unsigned char user_power_flag;
#ifdef TIME_SEARCH
extern INT32S search_time_hour  ;
extern INT32S search_time_min  ;
extern INT32S search_time_sec ;
#endif
typedef enum {
	NULL_TERM=0,
	NORMAL_=0x4d524f4e,
	ENDFILE=0x46444e45,
	LIST=0x5453494c,
	RIFF=0x46464952,
	AVI =0x20495641,
	auds=0x73647561,
	txts=0x73747874,
	vids=0x73646976,
	mids=0x7364696d,
	JUNK=0x4b4e554a,
	strh=0x68727473,
	strf=0x66727473,
	strd=0x64727473,
	strn=0x6e727473,
	movi=0x69766f6d,
	strl=0x6c727473,
	idx1=0x31786469,
	hdrl=0x6c726468,
	avih=0x68697661,
}FOURCC ;

typedef unsigned 	DWORD;
//typedef unsigned short WORD;
typedef char *STR;
typedef struct _chunk{
	FOURCC fcc;
	DWORD  cb;
}Chunk;

typedef struct _avimainheader { 
  FOURCC fcc; 
  DWORD  cb; 
  DWORD  dwMicroSecPerFrame; 
  DWORD  dwMaxBytesPerSec; 
  DWORD  dwPaddingGranularity; 
  DWORD  dwFlags; 
  DWORD  dwTotalFrames; 
  DWORD  dwInitialFrames; 
  DWORD  dwStreams; 
  DWORD  dwSuggestedBufferSize; 
  DWORD  dwWidth; 
  DWORD  dwHeight; 
  DWORD  dwReserved[4]; 
} AVIMAINHEADER; 
typedef struct _avistreamheader { 
   FOURCC fcc; 
   DWORD  cb; 
   FOURCC fccType; 
   FOURCC fccHandler; 
   DWORD  dwFlags; 
   WORD   wPriority; 
   WORD   wLanguage; 
   DWORD  dwInitialFrames; 
   DWORD  dwScale; 
   DWORD  dwRate; 
   DWORD  dwStart; 
   DWORD  dwLength; 
   DWORD  dwSuggestedBufferSize; 
   DWORD  dwQuality; 
   DWORD  dwSampleSize; 
   struct { 
       WORD left; 
       WORD top; 
       WORD right; 
       WORD bottom; 
   }  rcFrame; 
} AVISTREAMHEADER; 
/**** Stream format for video (strf) ****/
typedef struct _bitmapinfo {
	DWORD biSize;
	DWORD biWidth;
	DWORD biHeight;
	WORD 	biPlanes;
	WORD 	biBitCount;
	DWORD biCompression;
	DWORD biSizeImage;
	DWORD biXPelsPerMeter;
	DWORD biYPelsPerMeter;
	DWORD biClrUsed;
	DWORD biClrImportant;
} BITMAPINFOHEADER;
/**** Stream format for audio (stra) ****/
typedef struct AVI_header_strf_audio_s {
	WORD wFormatTag;         /* format type */
	WORD nChannels;          /* number of channels (i.e. mono, stereo...) */
	DWORD nSamplesPerSec;     /* sample rate */
	DWORD nAvgBytesPerSec;    /* for buffer estimation */
	WORD nBlockAlign;        /* block size of data */
	WORD wBitsPerSample;     /* number of bits per sample of mono data */
	WORD cbSize;             /* the count in bytes of the size of extra information (after cbSize) */
	#define AVI_STRF_MAX_EXTRA 12
	unsigned char  extra[AVI_STRF_MAX_EXTRA]; /* any extra information, e.g. mp3 needs this */
} AVI_header_strf_audio_t;
typedef struct _textinfo {  
    WORD wCodePage; 
    WORD wCountryCode; 
    WORD wLanguageCode; 
    WORD wDialect  ;
} TEXTINFO ;
typedef struct _avioldindex { 
   FOURCC  fcc; 
   DWORD   cb; 
   struct _avioldindex_entry { 
      DWORD   dwChunkId; 
      DWORD   dwFlags; 
      DWORD   dwOffset; 
      DWORD   dwSize; 
  } *aIndex; 
} AVIOLDINDEX; 
typedef struct _subtitlechunk { 
 FOURCC fcc; 
 DWORD cb; 
 STR duration; 
 STR subtitle ;
} SUBTITLECHUNK; 



typedef struct {
	Chunk ck;
	FOURCC type;
	DWORD offset;
}ChunkInfo;
typedef struct{
	ChunkInfo stack[10];
	unsigned  level;
}RIFFStack;


typedef struct _in_fp{
	int handle;
	unsigned oft;
	unsigned size;
}MYFILE;
typedef MYFILE* HANDLE;
typedef struct{
	HANDLE  fp;
	ChunkInfo cur;
	unsigned oft;
	RIFFStack stack;
	AVIMAINHEADER * mheader;
	AVISTREAMHEADER * streams;
	void ** strfs;
}RIFFTravel;
static MYFILE * myopen(char * name)
{
	MYFILE * fp;
	fp=(MYFILE *)AVMem_malloc(sizeof(MYFILE));
	if(!fp)
		return 0;
	fp->handle=open((const char *)name,O_RDONLY);
	fp->oft=0;
	struct stat sb;
	fstat(fp->handle,&sb);
	fp->size=sb.st_size;
	return fp;
}
static int myread(void * buf,unsigned size,unsigned count,MYFILE * fp)
{
	int ret;
	ret=read(fp->handle,buf,size*count);
	if((ret<=0)&&(size*count>0))
		fp->oft=fp->size+1;
	else
		fp->oft+=ret;
	return ret;
}
static void myclose(MYFILE * fp)
{
	close(fp->handle);
	AVMem_free(fp);
}
static unsigned mytell(MYFILE * fp)
{
	return fp->oft;
}
static unsigned myeof(MYFILE * fp)
{
	return (fp->oft>fp->size?1:0);
}
static unsigned myseek(MYFILE * fp,unsigned oft,unsigned where)
{
	fp->oft=oft;
	return lseek(fp->handle,oft,SEEK_SET);
}
static unsigned char push(ChunkInfo * info,RIFFStack * stack)
{
	if(stack->level>=sizeof(stack->stack)/sizeof(ChunkInfo))
		return 1;//Full
	memcpy(&stack->stack[stack->level],info,sizeof(ChunkInfo));
	stack->level++;
	return 0;
}
static unsigned char pop(ChunkInfo * info,RIFFStack * stack)
{
	if(stack->level==0)
		return 1;//empty
	if(info)
		memcpy(info,&stack->stack[stack->level-1],sizeof(ChunkInfo));
	stack->level--;
	return 0;
}
static void set_cur(RIFFTravel * travel)
{
	unsigned ret;
	ret=myread(&(travel->cur.ck),sizeof(Chunk),1,travel->fp);
	
	if(myeof(travel->fp))
	{
		travel->cur.type=ENDFILE;
		return;
	}
	
	switch(travel->cur.ck.fcc)
	{
		case LIST:
		case RIFF:
			travel->cur.type=travel->cur.ck.fcc;
			ret=myread(&(travel->cur.ck.fcc),sizeof(FOURCC),1,travel->fp);
			if(myeof(travel->fp))
			{
				travel->cur.type=ENDFILE;
				return;
			}
			break;
		case JUNK:
			travel->cur.type=JUNK;
			break;
		default:
			travel->cur.type=NORMAL_;
			break;
	}
	travel->cur.offset=mytell(travel->fp);
}
static void skip_cur(RIFFTravel * travel)
{
	unsigned target;
	switch(travel->cur.type)
	{
		case RIFF:
			target=travel->cur.ck.cb;
			break;
		case LIST:
			target=travel->cur.offset+travel->cur.ck.cb-4;
			break;
		default:
			target=travel->cur.offset+travel->cur.ck.cb;
			break;
	}
	target=(target+1)&~1;
	myseek(travel->fp,target,SEEK_SET);
}
RIFFTravel * init_riff_travel(unsigned char * name)
{
	RIFFTravel * travel;
	travel=(RIFFTravel *)malloc(sizeof(RIFFTravel));
	if(!travel)
		return 0;
	memset(travel,0,sizeof(RIFFTravel));
	travel->fp=myopen((char *)name);
	if(!travel->fp)
	{
		free(travel);
		return 0;
	}
	set_cur(travel);
	if(travel->cur.ck.fcc==AVI&&travel->cur.type==RIFF)
		return travel;
	myclose(travel->fp);
	free(travel);
	return 0;
}

void end_riff_travel(RIFFTravel * travel)
{
	int i;
	if(!travel)
		return;
	myclose(travel->fp);
	for(i=0;i<travel->mheader->dwStreams;i++)
	{
		if(travel->strfs[i])
			free(travel->strfs[i]);
	}
	if(travel->strfs)
		free(travel->strfs);
	if(travel->streams)
		free(travel->streams);
	if(travel->mheader)
		free(travel->mheader);
	free(travel);
}

ChunkInfo * get_next(RIFFTravel * travel)
{
	ChunkInfo * top;
	switch(travel->cur.type)
	{
		case LIST:
		case RIFF:
			push(&(travel->cur),&(travel->stack));
			break;
		default:
			skip_cur(travel);
			break;
	};
	do{
		set_cur(travel);
	
		switch(travel->cur.type)
		{
			case LIST:
				top=&travel->stack.stack[travel->stack.level-1];
				if((top->offset-4+top->ck.cb)<=(travel->cur.offset-12))
					pop((ChunkInfo*)0,&(travel->stack));
				break;
			case JUNK:
				skip_cur(travel);
				break;
		};
	}while(travel->cur.type==JUNK);
	return &(travel->cur);
}
ChunkInfo * get_cur(RIFFTravel * travel)
{
	return &(travel->cur);
}

FOURCC * get_path(FOURCC * path,RIFFTravel * travel)
{
	int i;
	for(i=0;i<travel->stack.level;i++)
	{
		path[i]=travel->stack.stack[i].ck.fcc;
	}
	path[i]=travel->cur.ck.fcc;
	i++;
	for(;i<sizeof(travel->stack.stack)/sizeof(ChunkInfo);i++)
	{
		path[i]=NULL_TERM;
	}
	return path;
}
int check_path(RIFFTravel * travel,FOURCC * in)
{
	FOURCC path[10];
	get_path(path,travel);
	if(memcpy(path,in,10))
		return 0;
	return 1;
}
unsigned get_cur_size(RIFFTravel * travel)
{
	return travel->cur.ck.cb;
}
void read_data(RIFFTravel * travel , void * data)
{
	ChunkInfo * p;
	unsigned offset;
	p=&travel->cur;
	switch(p->type)
	{
		case LIST:
		case RIFF:
			//pleas do not read LIST AND RIFF data;
			break;
		default:
			offset=p->offset;
			break;
	}
	myseek(travel->fp,offset,SEEK_SET);
	myread(data,p->ck.cb,1,travel->fp);
}
void process_avih(RIFFTravel * travel)
{
	AVIMAINHEADER	* mheader;
	mheader=(AVIMAINHEADER	*)malloc(travel->cur.ck.cb + sizeof(mheader->fcc) + sizeof(mheader->cb) );
	mheader->fcc=travel->cur.ck.fcc;
	mheader->cb=travel->cur.ck.cb;
	read_data(travel,&(mheader->dwMicroSecPerFrame));
	travel->mheader=mheader;
	travel->streams=(AVISTREAMHEADER *)malloc(mheader->dwStreams*sizeof(AVISTREAMHEADER));
	travel->strfs=(void**)AVMem_calloc(mheader->dwStreams,sizeof(void*));
}
void process_strl(RIFFTravel *travel,unsigned id)
{
	ChunkInfo * p;
	void * temp;
	BITMAPINFOHEADER * bm;
	AVI_header_strf_audio_t * audio_info;
	p=get_next(travel);
	do{
		switch(p->ck.fcc)
		{
			case strf:
				switch(travel->streams[id].fccType)
				{
					case auds:
						audio_info=(AVI_header_strf_audio_t *)malloc(p->ck.cb);
						read_data(travel,audio_info);
						travel->strfs[id]=audio_info;
						break;
					case txts:
						break;
					case vids:
						bm=(BITMAPINFOHEADER *)malloc(p->ck.cb);
						read_data(travel,bm);
						travel->strfs[id]=bm;
						break;
					case mids:
						break;
					
				}
				break;
			case strh:
				temp=malloc(p->ck.cb);
				read_data(travel,temp);
				memcpy(&travel->streams[id].fccType,temp,sizeof(travel->streams[id])-sizeof(Chunk));
				free(temp);
				break;
			case strn:
				break;
			case strd:
				break;
		}
		p=get_next(travel);
	}while(p->ck.fcc==strf || p->ck.fcc==strh || p->ck.fcc==strn || p->ck.fcc==strd);
	
}
void process_hdrl(RIFFTravel *travel)
{
	unsigned i;
	i=0;
	ChunkInfo * p;
	p=get_cur(travel);
	do{
		
		switch(p->ck.fcc)
		{
			case avih:
				process_avih(travel);
				p=get_next(travel);
				break;
			case strl:
				process_strl(travel,i);
				p=get_cur(travel);
				i++;
				break;
			default:
				p=get_next(travel);
				break;
		}
		if(i == travel->mheader->dwStreams)
				break;
	}while(p->ck.fcc==avih||p->ck.fcc==strl);
}






#ifdef SUPPORT_RM
void SetSubpicStatus(AVI_SUB_t status)
{
    subpic_status = status;
}
#endif

static void AviInit()
{
	#ifdef ENABLE_NETWORK	
	CHARSTR WinName[] = "WinMoviePlayBack";
	HWND *pHwnd = AWFindWinCtrlByName(WinName);

	if(!pHwnd)
	{
		GUICreateWindow(WinName) ;
		pHwnd = AWFindWinCtrlByName(WinName) ;
	}
	#endif	
    if (preview_video == 0)
    ShowWinMoviePlayBack();
     Set_subpic_enable(0);
    avi_playing_time = 0xffffffff;
    sub_txt_line1[0] = 0 ;
    sub_txt_line2[0] = 0 ;
    fffb_level = 1;
	zoom_level=0;//zoom_level=0:origin state
	#ifdef ZOOM_IN
	reduce_level = 0;
	#endif
}

void AviSetSubOn(INT8U flag)
{
    if(subpic_status <= NO_SUBPIC)
        return ;
    if(flag) 
    {
        subpic_status = SUBPIC_ON ;
    }
    else 
    {
        subpic_status = SUBPIC_OFF ;
    }
}

void get_avi_info(AVIINFO * info , char * name)
{
	RIFFTravel * travel;
	ChunkInfo * p;
	unsigned filesize;
	travel=init_riff_travel((unsigned char *)name);
	if(!travel)
		return;
	p=get_cur(travel);
	do{
		
		if(p->ck.fcc==hdrl)
		{
			process_hdrl(travel);
			p=get_cur(travel);
		}
		else
			p=get_next(travel);
		
	}while((travel->cur.type!=ENDFILE)&&(travel->cur.ck.fcc!=movi));
	filesize=travel->cur.ck.cb;
	unsigned i,tt;
	AVI_header_strf_audio_t* audio;
	BITMAPINFOHEADER * bm;
	info->width=travel->mheader->dwWidth;
	info->heigth=travel->mheader->dwHeight;
	tt=0;
	double len,scale,rate;
	for(i=0;i<travel->mheader->dwStreams;i++)
	{
		switch(travel->streams[i].fccType)
		{
			case auds:
				tt|=1;
				audio=(AVI_header_strf_audio_t*)travel->strfs[i];
				info->audio_channels=audio->nChannels;
				info->audio_codec=audio->wFormatTag;
				info->audio_kbps=audio->nAvgBytesPerSec*8/1000;
				break;
			case vids:
				tt|=2;
				bm=(BITMAPINFOHEADER *)travel->strfs[i];
				len=(double)travel->streams[i].dwLength;
				scale=(double)travel->streams[i].dwScale;
				rate=(double)travel->streams[i].dwRate;
				info->totaltime=len*scale/rate;
				info->video_codec = bm->biCompression;
				break;
		}
		if(tt==3)
			break;
	}
	filesize/=info->totaltime;
	info->video_kbps=(filesize*8/1000)-info->audio_kbps;
	
	end_riff_travel(travel);
}

INT8U GetAVIInfo(char *file_name, VIDEO_INFO *video_info){
	get_avi_info(&info, file_name); 
    switch (info.video_codec){
        // motion jpeg
        case 0x47504a4d:
	    case 0x47504a4c:
	        video_info->video_type = VIDEO_TYPE_MJPEG;
	        break;
	    // xvid
	    case 0x44495658:
	    case 0x58495658:
	        video_info->video_type = VIDEO_TYPE_XVID;
	        break;
	    //divx3.11
	    case 0x314c4f43:
	    case 0x33564944:
	    case 0x3334504d:
        // divx4
	    case 0x34564944:
	    case 0x58564944:
	    // divx5
	    case 0x35564944:
	    case 0x30355844:
	    // divx6
	    case 0x36564944:
	        video_info->video_type = VIDEO_TYPE_DIVX;
	        break;
        // mpeg4
        case 0x5634504d:
        case 0x34504d52:
        case 0x3234504d:
        case 0x3447504d:
	        video_info->video_type = VIDEO_TYPE_MP4;
	        break;
	    default: 
	        video_info->video_type = VIDEO_TYPE_UNKNOW;
            break;
    }
	video_info->audio_type = info.audio_codec;
	video_info->total_time = info.totaltime;
	video_info->size = (info.audio_kbps + info.video_kbps) * 125;
	return 1;
}

#ifdef RESUME_PLAY
extern RESUME_FILEINFO resume_file;
extern INT8U ResumePlayFlag;
extern INT8U ResumeFunction;
#endif

INT8U AviCmdResponse(AWMSG *pMsg, PCMDSET cmd_set)
{
    INT8U iRet = BREAK_EXECUTE_COMMAND ;

    switch(pMsg->msg_type){
    case MSG_COMMAND_SUCCESS:
        if(cmd_set->commands[0] == CM_LOAD_APP) {
			#ifdef RESUME_PLAY
				if((ResumePlayFlag == 1)&&(resume_file.time))
				{
					 send_player_message_with_param(CM_TIME_SEARCH, resume_file.time);
				}
			#endif
        }
        else if(cmd_set->commands[0] == CM_PLAY) {
            GPIO_UNMUTE;
        }
        iRet = GO_ON_EXECUTE_COMMAND ;
        break ;
    case MSG_COMMAND_FAIL:
//        AWAVIKeyDo(UOP_STOP) ;
//        iRet = GO_ON_EXECUTE_COMMAND ;
        break ;
    case MSG_COMMAND_FORBIDEN:
        break ;
    case MSG_COMMAND_NOT_SUPPORT:
    default:
        break ;
    }
    return iRet ;
}

int PlayAVIFile(char *file_name)
{
    AviInit() ;

    return AWLoadVideoApp(MEDIA_AVI, AviCmdResponse, file_name);
}

/* Callback from the playlist module when the next
 * playlist item has been retrieved. */
static void AVIPlaylistCb(Playlist_t *playlist, PlaylistItem_t *item, PlaylistStatus_t status)
{
    PAPPTASKARG pAVIAppArg;

    if(status == PLAYLIST_STATUS_OK) 
    {
        if((GetAppType(item->location) == MEDIA_OTHER) ||GetAppType(item->location) == MEDIA_NULL)
        {
            pAVIAppArg = AWGetAppArg(MEDIA_AVI) ;   
            AWAppSendMessage(pAVIAppArg->app_id, pAVIAppArg->aw_msg_q,  pAVIAppArg->aw_event_handle,
                             MSG_NOTIFICATION, NM_AVI_GET_NEXT, 0) ;
            return ;
        }
        
        if(GetAppType(item->location) != MEDIA_AVI) 
        {
            avi_processing_status = AVI_STATUS_SWITCHING;
            send_player_message(CM_QUIT);
            avi_playlist = playlist;
            avi_playitem = item;
        }
        else 
        {
            AWLockPlaylist(playlist);
            AWGUISendNMMessage(GetAppType(item->location), NM_PLAY_GENERAL, (INT32U)playlist) ;
        }
    }
    else if((status == PLAYLIST_STATUS_GET_NEXT) ||(status == PLAYLIST_STATUS_GET_PREV))
    {
            pAVIAppArg = AWGetAppArg(MEDIA_AVI) ;   
            AWAppSendMessage(pAVIAppArg->app_id, pAVIAppArg->aw_msg_q,  pAVIAppArg->aw_event_handle,
                             MSG_NOTIFICATION, ((status == PLAYLIST_STATUS_GET_NEXT) ? NM_AVI_GET_NEXT : NM_AVI_GET_PREV), 0) ;
            return ;
    }
    else 
    {
        AWGUISendNMMessage(MEDIA_AVI, NM_PLAY_AVI, 0);
    }
}

void AWAVIQuitProcess(void)
{
    avi_processing_status = AVI_STATUS_QUITTING;
    send_player_message(CM_QUIT);
    if(avi_playlist) {
        AWPlaylistDelete2(avi_playlist);
        avi_playlist = NULL;
    }
    GPIO_MUTE ;
#ifdef USE_NEW_SCREEN_SAVER 
    ScrSaverSet(SCREEN_SAVER_ON) ;
    ScrSaverReset() ;
#else
    if(gScreenSaveFlag&&(keytimer)&&(!AVTimerIsEnabled(keytimer)))
        AVTimerEnable(keytimer);
#endif

    subpic_status = NO_SUBPIC;
    Set_subpic_enable(0);
    if(device_removed){
        device_removed=0;
        return;
    }
   //AWShowFileList(1);
}

int RunAVIPlayer(Playlist_t *playlist)
{
    INT8U my_app_id ;
#ifdef SUPPORT_VGA
    int video_fd;
    video_fd=open("/dev/video",O_RDONLY);
    ioctl(video_fd, VIDEOIO_SET_WIDEOPTION,VIDEO_WIDEOPTION_NORMAL);
    close(video_fd);
#endif    
    if(avi_playlist) {
        if(AWPlaylistDelete2(avi_playlist) == 0) {
        avi_playlist = NULL;
        }
    }

    AWGetAppID(MEDIA_AVI, &my_app_id) ; 
    if (AWGetAppStatus(my_app_id) != APP_RUNNING) {
    AviInit() ;

    AWSetPlaylistAppCb(playlist, AVIPlaylistCb);
    avi_playlist = playlist;
    if((avi_playitem = AWGetCurrentPlaylistItem2(playlist)) == NULL) {
        if(AWGetStartPlaylistItem2(playlist) != PLAYLIST_STATUS_ASYNCH) {
            avi_playlist = NULL;
            return -1;
        }
    }
#ifdef USE_NEW_SCREEN_SAVER 
    ScrSaverSet(SCREEN_SAVER_OFF) ;
    ScrSaverReset() ;
#else
    if(gScreenSaveFlag&&keytimer)
    AVTimerDisable(keytimer);
#endif

    if(isMute) {// unMute
    	GPIO_MB_UNMUTE ;
    }
    else {
    	GPIO_MB_MUTE ;
    }

    String_Init_Time();
	
   
   
        AWAppRunning(my_app_id) ;
        avi_processing_status = AVI_STATUS_RUNNING;
    }
    else {
    	avi_playlist = NULL;
    	send_player_message(CM_QUIT);
        return -1;
    }

	
	if(GetMovieRepeatModePara() == (INT8U)0){
		if(NODIR_FLAG==0)
			AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_ONLYONE);
		else
			AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_REPEAT_ONE);
		}
	else if(GetMovieRepeatModePara() == 1){
		if(NODIR_FLAG==0)
			AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_ONLYONE);
		else
			AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_DIR_REPEAT);
		}
    return 0;
}


int PreviewAviPlayer(char *filename)
{
    INT8U my_app_id ;

    AWGetAppID(MEDIA_AVI, &my_app_id) ; 
    if (AWGetAppStatus(my_app_id) != APP_RUNNING) 
    {
        AWAppRunning(my_app_id) ;
        avi_processing_status = AVI_STATUS_RUNNING;
        PlayAVIFile(filename);
    }
    else 
    {
        send_player_message(CM_QUIT);
        return -1;
    }
    return 0;
}

int send_player_message(int cmd_id)
{
    PCMDSET pCmd = AWCommandSetMalloc() ;

    if(pCmd) 
    {
        pCmd->command_num = 1 ;
        pCmd->curr_executed_cmd_num = 0 ;
        pCmd->commands[0] = cmd_id;
        pCmd->commands_para[0] = 0 ;
        pCmd->cmd_timeout_value[0] = 2 ; 
        AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
        pCmd->ExecuteResultProcess = AviCmdResponse ;
        AWAddCommandSet(pCmd) ;

        return 0;
    }

    return -1;
}

int send_player_message_with_param(int cmd_id, int param)
{
    PCMDSET pCmd = AWCommandSetMalloc() ;

    if(pCmd) 
    {
        pCmd->command_num = 1 ;
        pCmd->curr_executed_cmd_num = 0 ;
        pCmd->commands[0] = cmd_id;
        pCmd->commands_para[0] = param ;
        pCmd->cmd_timeout_value[0] = 2 ; 
        AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
        pCmd->ExecuteResultProcess = AviCmdResponse ;
        AWAddCommandSet(pCmd) ;

        return 0;
    }

    return -1;
}

void AWAVIQuitProcess2(AWMSG *pMsg)
{
#ifdef RESUME_PLAY
    if(ResumeFunction == 1)
    {
        ResumePlayFlag = 0;
    #ifdef SUPPORT_STANDBY
        extern char iPowerFlag;
        if(iPowerFlag == 0)
    #endif
        {
    	    resume_file.time = 0;
    	    SetResumePlayFlagPara(0);
    	}
    #ifdef SUPPORT_STANDBY
    	else
    	{
        #if RESUME_INTERVAL_TIME
        //
        #else
            SetResumePlayFlagPara(1);
        #endif
            SetResumeTimePara(resume_file.time);
    	}
    #endif
    }
#endif
	if(device_removed){
        device_removed=0;
        return;
    }
	if(user_power_flag)
		return ;
	
#if  HOTKEYENABLE  
	if(hotkey_flag){
		ReloadLogo();
		APPHotKeyProcess(&last_hotkey);
		hotkey_flag = 0 ;
		return ;
	}
#endif                 
	
    if(avi_processing_status == AVI_STATUS_SWITCHING) {
        AWLockPlaylist(avi_playlist);
        AWGUISendNMMessage(GetAppType(avi_playitem->location), NM_PLAY_GENERAL, (INT32U)avi_playlist) ;
        avi_playlist = NULL;
        return ;
    }

#ifdef SUPPORT_VGA
    int video_fd;
    video_fd=open("/dev/video",O_RDONLY);
    ioctl(video_fd, VIDEOIO_SET_WIDEOPTION,VIDEO_WIDEOPTION_WIDE);
    close(video_fd);
#endif
	if(preview_video == 1){
		Update_Video_PreviewScreen_Screen(0);
		disable_video_layer();
	}
	else
	{
	//    GUIHideWindow(WinMoviePlayBack) ;
	}
	
	if(LogoResum == 1){
		ReloadLogo();
		ResumFromLogo();
		LogoResum = 0 ;
	}
	else if(PlayBackResume == 1){
		ReloadLogo();
		ResumFromMoviePlayBack();
		PlayBackResume = 0 ;
	}
	else if(PlayBackHome == 1){
		ReloadLogo();
		GUIShowWindow(WinDeviceSelect);
		PlayBackHome = 0 ;
	}
	else if(LogoHome == 1){
		ReloadLogo();
		GUIShowWindow(WinDeviceSelect);
		LogoHome = 0 ;
	}
	else {
		
		if(NODIR_FLAG == 0){
			ReloadLogo();
			GUIShowWindow(WinFileList);
		}
		else {
			if(preview_video == 1){
				preview_video = 0 ;
			}
			/*
			else {
				ReloadLogo();
				GUIShowWindow(WinLogo);
			}
			*/
		}
	}
	
	return ;

}


void avi_play_preview(char *filename) 
{
	send_player_message(CM_STOP);
	ShowWinMoviePlayBack();
	PlayAVIFile(filename);
}

void AWAVIKeyDo(INT32S key)
{
	PCMDSET pCmd ;
	INT32U fffb = fffb_level;
	
    if((preview_video==1) && (key!=UOP_STOP))
       return;		
#ifdef KOREAR_REMOTE
	if(zoom_level == 0)
		{
		switch(key){
			case UOP_UP:
				key = UOP_PREVIOUS_CHAP;
				break;
			case UOP_DOWN:
				key = UOP_NEXT_CHAP;
				break;
			case UOP_LEFT:
				key = UOP_FAST_BACKWARD;
				break;
			case UOP_RIGHT:
				key = UOP_FAST_FORWARD;
				break;
			}
		}
#endif	
	switch(key){
		case UOP_END_PAUSE:
            fffb_level = 1;     
            send_player_message(CM_PLAY);
			break;
					
        case UOP_FAST_FORWARD:
            if (fffb_level & FB_TYPE) {
                fffb--;
                if((fffb & FFFB_MASK) == 1){
                	fffb = fffb_level = 1;
                	send_player_message(CM_PLAY);
                	break;
                }
                else{
					pCmd = AWCommandSetMalloc() ;
					pCmd->command_num = 1 ;
					pCmd->curr_executed_cmd_num = 0 ;
					pCmd->commands[0] = CM_BACKWARD_SCAN ;
					pCmd->commands_para[0] = fffb & FFFB_MASK ;
					pCmd->cmd_timeout_value[0] = 2 ; 
					AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
					pCmd->ExecuteResultProcess = AviCmdResponse ;
					AWAddCommandSet(pCmd) ;
					break;
                }
            }
            else if (fffb_level < MAX_FF_LEVEL) {
                fffb++;
            }
            else {
                fffb_level = 1;     
                send_player_message(CM_PLAY);
    			break;
            }
			pCmd = AWCommandSetMalloc() ;
			pCmd->command_num = 1 ;
			pCmd->curr_executed_cmd_num = 0 ;
			pCmd->commands[0] = CM_FORWARD_SCAN ;
			pCmd->commands_para[0] = fffb ;
			pCmd->cmd_timeout_value[0] = 2 ; 
			AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
			pCmd->ExecuteResultProcess = AviCmdResponse ;
			AWAddCommandSet(pCmd) ;
			break;
			
        case UOP_FAST_BACKWARD:
            if (!(fffb & FB_TYPE)) {
            	if(fffb == 1)
                	fffb = 2 | FB_TYPE;
                else {
                	fffb-- ;
                	if(fffb == 1){
                		fffb = fffb_level = 1;
                		send_player_message(CM_PLAY);
                		break;
                	}
                	else {
						pCmd = AWCommandSetMalloc() ;
						pCmd->command_num = 1 ;
						pCmd->curr_executed_cmd_num = 0 ;
						pCmd->commands[0] = CM_FORWARD_SCAN ;
						pCmd->commands_para[0] = fffb ;
						pCmd->cmd_timeout_value[0] = 2 ; 
						AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
						pCmd->ExecuteResultProcess = AviCmdResponse ;
						AWAddCommandSet(pCmd) ;
						break;
					}
                }
			}
            else if ((fffb & FFFB_MASK) < MAX_BF_LEVEL) {
                fffb ++ ;
            }
            else {
                fffb_level = 1;     
                send_player_message(CM_PLAY);
    			break;
            }
			pCmd = AWCommandSetMalloc() ;
			pCmd->command_num = 1 ;
			pCmd->curr_executed_cmd_num = 0 ;
			pCmd->commands[0] = CM_BACKWARD_SCAN ;
			pCmd->commands_para[0] = fffb & FFFB_MASK ;
			pCmd->cmd_timeout_value[0] = 2 ; 
			AWGetAppID(MEDIA_AVI, &pCmd->app_id) ;
			pCmd->ExecuteResultProcess = AviCmdResponse ;
			AWAddCommandSet(pCmd) ;
			break;        	

		case UOP_AUDIO:
			send_player_message(CM_AUDIO_CHANGE) ;
			break;
		case UOP_PAUSE:
			send_player_message(CM_PAUSE) ;
			break;
		case UOP_RESUME:
		case UOP_STOP:
			PlayBackResume=1;
			AWAVIQuitProcess();
			
			
        case UOP_NEXT_CHAP:
			if(NODIR_FLAG==0)
				break;
			else{
	            if(avi_processing_status != AVI_STATUS_RUNNING) {
	                break ;
	            }
	            GetNextOrPrev = MANUAL_GET_NEXT_CHAP;
	            avi_processing_status = AVI_STATUS_SKIPPING;
	            send_player_message(CM_STOP);
	            AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_DIR_REPEAT);
	            if(AWGetNextPlaylistItem2(avi_playlist) != PLAYLIST_STATUS_ASYNCH) {
	                AWAVIQuitProcess();
	            }
	            
				if( (preview_video == 0)&&(AWGetTopWindow(gpFocusWin)!= AWFindWinCtrlByName(WinMoviePlayBack))){
					ShowWinMoviePlayBack();
				}
		            break ;
			}
			
        case UOP_PREVIOUS_CHAP:
		if(NODIR_FLAG==0)
			break;
		else{
	            if(avi_processing_status != AVI_STATUS_RUNNING) {
	                break ;
	            }
	            GetNextOrPrev = MANUAL_GET_PRE_CHAP;
	            avi_processing_status = AVI_STATUS_SKIPPING;
	            send_player_message(CM_STOP);
	            AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_DIR_REPEAT);
	            if(AWGetPrevPlaylistItem2(avi_playlist) != PLAYLIST_STATUS_ASYNCH) {
	                AWAVIQuitProcess();
	            }
				if( (preview_video == 0)&&(AWGetTopWindow(gpFocusWin)!= AWFindWinCtrlByName(WinMoviePlayBack))){
					ShowWinMoviePlayBack();
				}	            
	            break ; 
			}

        case UOP_ZOOM:
			#ifdef ZOOM_IN
			if(reduce_level != 0){
				reduce_level = 0;
				AW_SetVideoZoomDown(reduce_level);
			}else
			#endif
			send_player_message(CM_ZOOM_CHANGE) ;
            break;            

        case UOP_LEFT:
            send_player_message(CM_KEY_LEFT) ;
            break;            
            
        case UOP_RIGHT:
            send_player_message(CM_KEY_RIGHT) ;
            break;            
	case UOP_OSD:
		if (AWGetTopWindow(gpFocusWin) == AWFindWinCtrlByName(MoviePlayInfoBar))
		{	break;
		}
		else
		{
			if (subpic_status == SUBPIC_ON)
			{	
				PHWND hwnd = AWFindWinCtrlByName(MoviePlayInfoBar);
				GUIShowWindow(WinMoviePlayBack);
				
				AWShowWinControl(hwnd,1);
				//AWSetFocus(hwnd);
				
				//GUIShowWindow(WinMoviePlayBack);
			}
		}
		break;
        case UOP_UP:
            send_player_message(CM_KEY_UP) ;
            break;            

        case UOP_DOWN:
            send_player_message(CM_KEY_DOWN) ;
            break;            
        case UOP_ANGLE:
            send_player_message(CM_ANGLE_CHANGE);
            break;   
	#ifdef TIME_SEARCH
	case UOP_TIME_PLAY:
		INT32S  search_time = (search_time_hour<<16)|(search_time_min<<8)|search_time_sec;
		send_player_message_with_param(CM_TIME_SEARCH, search_time);
	    break;
	#endif
        // following code is used to test display adjustment
        // 1-5 is five different mode
        // 0 is for toggle between them
        case UOP_1:
        case UOP_2:
        case UOP_3:
        case UOP_4:
        case UOP_5:
            send_player_message_with_param(CM_DISPLAY_ADJUST, key-UOP_1);
            break;
        case UOP_0:
	 case UOP_169_43:
            send_player_message_with_param(CM_DISPLAY_ADJUST, DISPLAY_ADJUST_TOGGLE);
            break;
	#ifdef ZOOM_IN
	 case UOP_ZOOM_IN:
	    if(MovieResetZoomLevel())
	    {
	    	send_player_message(CM_ZOOM_RETURN);
	    }else{
		reduce_level++;
		if(reduce_level>3)
			reduce_level = 0;
		AW_SetVideoZoomDown(reduce_level);
	    }
		break;
	#endif
		default:
			break;	
	}
	return ;
}

void AWAVIKeyProcess(AWMSG *pMsg)
{
    if((avi_processing_status == AVI_STATUS_QUITTING) ||(avi_processing_status == AVI_STATUS_SWITCHING)) 
    { // no key responding during App quit processing
        return ;
    }
    AWAVIKeyDo(pMsg->msg_value) ;
}

#if (defined TV_MODE_720P)&&(defined AVI_SUBTITLE_ZOOM)
static INT8U x_ratio = 2;
static INT8U y_ratio = 2; 
#endif
PIXELVAL oldcolor;
#define GRAY_COLOR 2
void AWAVINotificationProcess(AWMSG *pMsg)
{
    PHWND hwnd = AWFindWinCtrlByName(AviSubCtrl) ;
    char **sub_text = NULL;
    PlaylistItem_t *item;
    Playlist_t *playlist;
    INT8U my_app_id ;
    char *p = NULL;
	divx_subtitle_showdata *divx_subtitle = NULL;
    switch(pMsg->msg_id)
    {
        case NM_AVI_PLAYTIME:
        if (preview_processing == 0) {
            if(avi_playing_time != (pMsg->msg_value/90000)) 
            {
                avi_playing_time = pMsg->msg_value/90000 ;
            }
            gPlayerUpdateVideofPlayTime(avi_playing_time);
        }
		if(GetNextOrPrev != NORMAL_GET_CHAP)
			GetNextOrPrev = NORMAL_GET_CHAP;
        break ;
    case NM_AVI_STATUS:
        if(pMsg->msg_value == AVI_PLAY) {
#ifdef USE_NEW_SCREEN_SAVER 
            ScrSaverSet(SCREEN_SAVER_OFF) ;
            ScrSaverReset() ;
#else
            if(gScreenSaveFlag&&keytimer)
                AVTimerDisable(keytimer);
#endif
            fffb_level = 1;     
        }
		else if(pMsg->msg_value == AVI_PAUSE) {
#ifdef USE_NEW_SCREEN_SAVER 
            ScrSaverSet(SCREEN_SAVER_ON) ;
            ScrSaverReset() ;
#else
            if(gScreenSaveFlag&&(keytimer)&&(!AVTimerIsEnabled(keytimer)))
                AVTimerEnable(keytimer);
#endif
        }

        break;
    case NM_AVI_FFFB_SPEED:
        fffb_level = pMsg->msg_value;
        break;
    case NM_AVI_VIDEO_ZOOMLEVEL:
	zoom_level = pMsg->msg_value;
        break;
    case NM_AVI_AUDIO_INFO:
        info.audio_codec=(pMsg->msg_value) & 0xff   ;
        break;
    case NM_AVI_SUBTITLE_INFO:
        if(pMsg->msg_value) 
        {
            subpic_status = SUBPIC_OFF ;
        }
        else 
        {
            subpic_status = NO_SUBPIC ;
        }
        UpdateAviSub() ;
        break ;
    case NM_AVI_SUBTITLE_TEXT:
        if(subpic_status != SUBPIC_ON) 
        {
            break;
        }
        
        if(pMsg->msg_value) 
        {
            sub_text = ((subtext_t *)pMsg->msg_value)->text;
            if(hwnd) 
            {
#if 1
                if((sub_text[0])&&(sub_text[1]))
                {
                    strcpy(sub_txt_line1,sub_text[0]) ;
                    strcpy(sub_txt_line2,sub_text[1]) ;
                }
                else if(sub_text[0])
                {
                    strcpy(sub_txt_line2,sub_text[0]) ;
                    sub_txt_line1[0] = 0 ;
                }
                else if(sub_text[1])
                {
                    strcpy(sub_txt_line2,sub_text[1]) ;
                    sub_txt_line1[0] = 0 ;
                }
                else
                {
                    sub_txt_line1[0] = 0 ;
                    sub_txt_line2[0] = 0 ;
                }
#else
                if(sub_text[0]) 
                {
                    strcpy(sub_txt_line1,sub_text[0]) ;
                }
                else 
                {
                    sub_txt_line1[0] = 0 ;
                }
                
                if(sub_text[1]) 
                {
                    strcpy(sub_txt_line2,sub_text[1]) ;
                }
                else 
                {
                    sub_txt_line2[0] = 0 ;
                }
#endif                
                if(AWIsVisibleWinControl(hwnd)) 
                {
                #if (defined TV_MODE_720P)&&(defined AVI_SUBTITLE_ZOOM)
                    if(CurrentOsdSize == OsdSize720p)
                        AWSetFontZoom(x_ratio, y_ratio);
                #endif
                    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO, 0) ;
                    oldcolor=AWSetForeground(GRAY_COLOR);
                    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO_CENTER, 1) ;
                    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO_CENTER, 2) ;	
                    AWSendMessage(hwnd,WM_PAINT_FINISH,0);
                    AWSetForeground(oldcolor);
                #if (defined TV_MODE_720P)&&(defined AVI_SUBTITLE_ZOOM)
                    if(CurrentOsdSize == OsdSize720p)
                        AWSetFontZoom(1, 1);
                #endif
                }
            }
        }
        else 
        {
            sub_txt_line1[0] = 0 ;
            sub_txt_line2[0] = 0 ;
            
            if((hwnd) && (AWIsVisibleWinControl(hwnd))) 
            {
            #if (defined TV_MODE_720P)&&(defined AVI_SUBTITLE_ZOOM)
                if(CurrentOsdSize == OsdSize720p)
                    AWSetFontZoom(x_ratio, y_ratio);
            #endif
			    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO, 0) ;
			    oldcolor=AWSetForeground(GRAY_COLOR);
			    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO_CENTER, 1) ;
			    AWSendMessage(hwnd, WM_PAINT_DRAW_INFO_CENTER, 2) ;
			    AWSendMessage(hwnd,WM_PAINT_FINISH,0);
			    AWSetForeground(oldcolor);
            #if (defined TV_MODE_720P)&&(defined AVI_SUBTITLE_ZOOM)
                if(CurrentOsdSize == OsdSize720p)
                AWSetFontZoom(1, 1);
            #endif
            }
        }
        break;
    case NM_AVI_SUBTITLE_BMP:
		int i=0;
	    if(subpic_status != SUBPIC_ON)
			break;
	PHWND hwnd = AWFindWinCtrlByName(MoviePlayInfoBar);
	if(AWIsVisibleWinControl(hwnd))
	{	
		break;
	}
	else
	{
		if (AWGetTopWindow(gpFocusWin) != AWFindWinCtrlByName(WinDivxSub))
		{
			
			GUIShowWindow(WinDivxSub);
			
		}
		/*else 
		{
			break;
		}*/
	}
	
		if (!pMsg->msg_value){
			AWClearScreen();
			break;	
		}
		divx_subtitle = (divx_subtitle_showdata *)pMsg->msg_value;
		SetWinDivx_SubTitlePalette_4(divx_subtitle->pattern,divx_subtitle->background,divx_subtitle->emphasis1,divx_subtitle->emphasis2);
	if (CurrentOsdSize == OsdSize720p)
	{
		for (i=0; i<divx_subtitle->height; i+=2){
			AWBitmap(divx_subtitle->left+250, 
			         divx_subtitle->top+i+250, 
			         (divx_subtitle->width+3)/4, 
			         (INT8U *)(divx_subtitle->prtData+i*((divx_subtitle->width+7) & ~7)/8));
			AWBitmap(divx_subtitle->left+250,
			         divx_subtitle->top+i+1+250,
			         (divx_subtitle->width+3)/4,
			         (INT8U *)(divx_subtitle->prtData+i*((divx_subtitle->width+7) & ~7)/8+OSD_HALF_SIZE));
		}		
	}
	else
	{
		for (i=0; i<divx_subtitle->height; i+=2){
			AWBitmap(divx_subtitle->left, 
			         divx_subtitle->top+i, 
			         (divx_subtitle->width+3)/4, 
			         (INT8U *)(divx_subtitle->prtData+i*((divx_subtitle->width+7) & ~7)/8));
			AWBitmap(divx_subtitle->left,
			         divx_subtitle->top+i+1,
			         (divx_subtitle->width+3)/4,
			         (INT8U *)(divx_subtitle->prtData+i*((divx_subtitle->width+7) & ~7)/8+OSD_HALF_SIZE));
		}	
	}
		break;
    case NM_AVI_END_OF_PLAY:
        avi_playing_time = 0xffffffff ;
        if(pMsg->msg_value == AVI_PLAYEND) {

        #ifdef RESUME_PLAY
            if(ResumePlayFlag == 1)
            {
                ResumePlayFlag = 0;
	    		AWAVIQuitProcess();
	    		break;
            }
        #endif

            if(avi_processing_status != AVI_STATUS_RUNNING) {
                break ;
            }

            if(subpic_status == SUBPIC_ON) {
			AWSendMessage(hwnd, WM_PAINT_DRAW_INFO, 0) ;
            }
			
            if(GetMovieRepeatModePara() == (INT8U)0){
			if(NODIR_FLAG==0)
				AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_ONLYONE);
			else
				AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_REPEAT_ONE);	
	            	}
            else if(GetMovieRepeatModePara() == 1){
			if(NODIR_FLAG==0)
				AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_ONLYONE);
			else
				AWSetPlaylistPlayMode2(avi_playlist, PLAY_MODE_DIR_REPEAT);			
	        }
			
            avi_processing_status = AVI_STATUS_SKIPPING;
            if(AWGetNextPlaylistItem2(avi_playlist) != PLAYLIST_STATUS_ASYNCH) {
                AWAVIQuitProcess();
            }
        }
    	else if((pMsg->msg_value == AVI_ERROR)||(pMsg->msg_value == AVI_UNSUPPORT)){
    		if((preview_video != 1)&&((NODIR_FLAG == 0)||(NODIR_FLAG == 2))){
				ShowWinConfirm(CONFIRM_MOVIEPLAYBACK);
				
/*
				if(GetNextOrPrev == MANUAL_GET_PRE_CHAP){
					goto GET_PREV ;
				}
				else {
					goto GET_NEXT ;
				}
*/
	    	}
	    	else {
	    		GetCurrUnSupportItemName();
	    		AWAVIQuitProcess();
	    	}
	    		
    	}
        break ;
        
        
    case NM_AVI_GET_NEXT:
GET_NEXT:    	
        if((avi_processing_status == AVI_STATUS_QUITTING) ||
           (avi_processing_status == AVI_STATUS_SWITCHING)) { // no key responding during App quit processing
            break ;
        }
        avi_processing_status = AVI_STATUS_SKIPPING;
        if(AWGetNextPlaylistItem2(avi_playlist) != PLAYLIST_STATUS_ASYNCH) {
            AWAVIQuitProcess();
        }
        break ;
    case NM_AVI_GET_PREV:
GET_PREV:    	
        if((avi_processing_status == AVI_STATUS_QUITTING) ||
           (avi_processing_status == AVI_STATUS_SWITCHING)) { // no key responding during App quit processing
            break ;
        }
        avi_processing_status = AVI_STATUS_SKIPPING;
        if(AWGetPrevPlaylistItem2(avi_playlist) != PLAYLIST_STATUS_ASYNCH) {
            AWAVIQuitProcess();
        }
        break ;
    case NM_PLAY_AVI:
    case NM_PLAY_GENERAL:
        if(!pMsg->msg_value) {
            AWAVIQuitProcess();
            break;
        }
        playlist = (Playlist_t *)pMsg->msg_value;
        AWUnLockPlaylist(playlist);
        if(AWPlaylistIsInvalid(playlist)) {
            if((INT32U)avi_playlist == (INT32U)playlist) {
                avi_playlist = NULL;
            }
            AWPlaylistDelete2(playlist);
            break ;
        }
        AWGetAppID(MEDIA_AVI, &my_app_id) ;
        if (AWGetAppStatus(my_app_id) != APP_RUNNING) {
            if (RunAVIPlayer(playlist)) {
                AWPlaylistDelete2(playlist);
                AWShowFileList(1);
                ReloadLogo() ;
            }
            else {
                item = avi_playitem;
                goto PLAY_AVI_FILE ;
            }
        }
        else {
            item = AWGetCurrentPlaylistItem2(playlist);
PLAY_AVI_FILE:
            if(item) {
    	    #ifdef RESUME_PLAY
    		    if((preview_video == 0)&&(ResumeFunction == 1))
    		    {
        		  	memset(resume_file.file_name,0,100);
        			strcpy(resume_file.file_name,item->location);
        			SetResumeFilePara(resume_file.file_name);
        			resume_file.time = 0;
        			SetResumeTimePara(resume_file.time);
        		#if RESUME_INTERVAL_TIME
        			SetResumePlayFlagPara(1);
        	    #else
        			SetResumePlayFlagPara(0);
        	    #endif
    		    }
            #endif
	         p = strrchr(item->location, '/');	
             sprintf(gCurOnlyFileName,"%s",p+1);
//                get_avi_info(&info,item->location); 
		  #ifdef TIME_SEARCH
		  Get_FileInfo(gCurOnlyFileName);
		  #endif		  
                avi_playing_time = 0xffffffff;
                fffb_level = 1;
				zoom_level = 0;
                if(avi_processing_status == AVI_STATUS_SKIPPING) {
                    avi_processing_status = AVI_STATUS_RUNNING;
                }
                if(PlayAVIFile(item->location)) {
                    AWAVIQuitProcess();
                }
            } else {
                AWAVIQuitProcess();
            }
        }
        break ;
    default:
        break ;
    }
    return ;
}

void AWAVIBroadCastProcess(AWMSG* pMsg)
{
	PlaylistItem_t *item;
	CHARSTR* temp;

#ifdef RESUME_PLAY
    if((ResumePlayFlag == 1)&&(pMsg->msg_id==BM_DEVICE_PRE_UNMOUNT))
    {
		temp=((DEV_MOUNT_INFO *)(pMsg->msg_value))->mount_point_name;
		if (strncmp(resume_file.file_name, temp, 5) == 0) 
		{
			SetForceCloseMediaApp();
			device_removed=1; // move this line before "AWAVIQuitProcess" because device_removed will be used during call AWAVIQuitProcess
			preview_video=0;
			AWAVIQuitProcess();
            return ;
		}
    }    
#endif

	if(!avi_playlist) 
	{
		return ;
	}

	item = AWGetCurrentPlaylistItem2(avi_playlist);

	if(!item) 
	{
		return ;
	}

	if(pMsg->msg_id==BM_DEVICE_PRE_UNMOUNT)
	{
		temp=((DEV_MOUNT_INFO *)(pMsg->msg_value))->mount_point_name;
		if (strncmp(item->location, temp, strlen(temp)) == 0) 
		{
			SetForceCloseMediaApp();
			device_removed=1; // move this line before "AWAVIQuitProcess" because device_removed will be used during call AWAVIQuitProcess
			preview_video=0;
			AWAVIQuitProcess();
		}
	}
}    

void AWAVIMsgProcess(AWMSG *pMsg)
{
    switch(pMsg->msg_type)
    {
        case MSG_INPUT_EVENT:
            if(pMsg->msg_id == WM_KEYDOWN)
            {
                AWAVIKeyProcess(pMsg) ;
            }
            break ;
        case MSG_NOTIFICATION:
                AWAVINotificationProcess(pMsg) ;
		    if (preview_video == 0)
                gPlayerPlayState(1,pMsg->msg_id,pMsg->msg_value,0,0);
            break ;
        case MSG_QUIT:
            AWAVIQuitProcess2(pMsg) ;
            break;
        case MSG_BROADCAST:
            AWAVIBroadCastProcess(pMsg);
            break;    
        default:
            break ;
    }
    
    return ;
}

